home *** CD-ROM | disk | FTP | other *** search
- /*
- * rename() - rename a file
- */
- #include "lib.h"
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <signal.h>
- #include <errno.h>
-
- #define PUBLIC
-
- #ifndef NULL
- #define NULL (void *) 0
- #endif
-
- extern int errno;
-
- /*========================================================================*\
- ** rename() **
- \*========================================================================*/
- PUBLIC int
- rename( from, to )
- _CONST char *from, *to;
- {
- /*
- * Attempts to link 'from' as 'to'. If 'to' exists it is unlinked.
- *
- * NOTE: 'rename()' will not rename across file systems or
- * file types. Also, if an attempt is made to copy across
- * file systems both files will be left intact and an
- * error will be returned.
- */
- struct stat s_to, s_from;
- void (*s_int)(), (*s_hup)(), (*s_quit)();
- int ret = 0;
-
- /*
- * get status if 'from' and 'to', if either attemp fails we know
- * one of the files doesn't exist. if 'from' doesn't exist then
- * return an error condition. if both files exist then test if
- * their both on the same file system. if 'to' doesn't exist then
- * don't worry about it, it soon will.
- */
- if (stat( from, &s_from ) == 0) {
- if (stat( to, &s_to ) == 0) {
- if ( s_to.st_dev == s_from.st_dev ) {
- errno = EXDEV;
- return( -1 );
- }
- }
- /*
- * Ignore SIGINT, SIGHUP, and SIGQUIT until
- * we'er finished.
- */
- s_int = signal( SIGINT, SIG_IGN );
- s_hup = signal( SIGHUP, SIG_IGN );
- s_quit = signal( SIGQUIT, SIG_IGN );
- /*
- * does 'to' exist? if so remove it
- */
- ret = unlink( to );
- if ((ret = link( from, to )) == 0)
- ret = unlink( from );
- /*
- * Restore signals
- */
- signal( SIGINT, s_int );
- signal( SIGHUP, s_hup );
- signal( SIGQUIT, s_quit );
- return( ret );
- } else
- return( -1 );
- }
-